package org.zuel.boot.demo.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.zuel.boot.demo.constant.AuthConstant;
import org.zuel.boot.demo.Dao.*;
import org.zuel.boot.demo.model.*;
import org.zuel.boot.demo.service.IAuthQueryService;

import java.util.ArrayList;
import java.util.List;

@Service
public class AuthQueryService implements IAuthQueryService {

    private final DemoUserRoleMapper userRoleMapper;

    private final DemoRolePermMapper rolePermMapper;

    private final DemoUserMapper userMapper;

    private final DemoRoleMapper roleMapper;

    private final DemoPermMapper permMapper;

    @Autowired
    public AuthQueryService(DemoUserRoleMapper userRoleMapper,
                            DemoRolePermMapper rolePermMapper,
                            DemoUserMapper userMapper,
                            DemoRoleMapper roleMapper,
                            DemoPermMapper permMapper) {
        this.userRoleMapper = userRoleMapper;
        this.rolePermMapper = rolePermMapper;
        this.userMapper = userMapper;
        this.roleMapper = roleMapper;
        this.permMapper = permMapper;
    }
    //感觉是固定流程，不过应该属于需要谁的参数就需要引入谁的mapper

    @Override
    public List<DemoUser> queryUsername(String username) {//那你不是炸了吗，这么好理解
        DemoUserExample example = new DemoUserExample();//迅速构建一个查询
        example.createCriteria().andDeletedEqualTo(false).andUsernameEqualTo(username);//为这个查询书写具体内容
        return userMapper.selectByExample(example);
    }//这不就是在写Dao吗，只不过完全不用写sql了，起飞

    @Override
    public List<DemoRole> queryRolesByUser(Integer user) {//通过用户找角色
        if (user == null) {
            return new ArrayList<>();
        }
        // 查询关联关系
        DemoUserRoleExample mapExample = new DemoUserRoleExample();
        mapExample.setDistinct(true);
        DemoUserRoleExample.Criteria mapCriteria = mapExample.createCriteria();
        mapCriteria.andDeletedEqualTo((byte) 0);
        mapCriteria.andUserIdEqualTo(user);
        List<DemoUserRole> mapList = userRoleMapper.selectByExample(mapExample);
        if (mapList == null || mapList.isEmpty()) {
            return new ArrayList<>();
        }//我以为是啥，原来就是个返回值
        // 查询角色
        List<Integer> roleIds = new ArrayList<>();
        mapList.forEach(map -> {
            if (!roleIds.contains(map.getRoleId())) {
                roleIds.add(map.getRoleId());
            }
        });
        DemoRoleExample example = new DemoRoleExample();
        DemoRoleExample.Criteria criteria = example.createCriteria();
        criteria.andDeletedEqualTo(false);
        criteria.andIdIn(roleIds);
        return roleMapper.selectByExample(example);
    }

    @Override
    public List<DemoPerm> queryPermsByUser(Integer user) {//可以理解吧，用户查权限本身就需要两层逻辑，一层一层往下查
        // 查询角色
        List<DemoRole> roles = queryRolesByUser(user);
        if (roles.size() == 0) {
            return new ArrayList<>();
        }
        // 查询权限
        List<Integer> roleIds = new ArrayList<>();
        roles.forEach(role -> roleIds.add(role.getId()));
        return queryPermsByRoles(roleIds);
    }

    @Override
    public List<DemoPerm> queryPermsByRoles(List<Integer> roles, Integer annoStatus) {//参数：
        //roles：角色 ID 列表，表示需要查询权限的角色集合。
        //annoStatus：权限的匿名状态（可选参数），用于过滤权限是否允许匿名访问。
        //返回值：返回一个 List<DemoPerm>，表示与这些角色关联的权限列表。

        if (roles == null || roles.size() == 0) {
            return new ArrayList<>();
        }
        // 查询关联关系，而example就是用来构建查询的！
        DemoRolePermExample mapExample = new DemoRolePermExample();
        mapExample.setDistinct(true);//查询结果要去重
        DemoRolePermExample.Criteria mapCriteria = mapExample.createCriteria();
        mapCriteria.andDeletedEqualTo((byte) 0);//过滤掉已被删除的记录（andDeletedEqualTo((byte) 0)）因为deleted是逻辑删除
        mapCriteria.andRoleIdIn(roles);//在传入的角色列表中的记录（andRoleIdIn(roles)），roles其实不是实体类，观察形参能看到其就是id的list
        List<DemoRolePerm> mapList = rolePermMapper.selectByExample(mapExample);//获得结果list，不过由于关联表中只有id数据
        if (mapList == null || mapList.size() == 0) {
            return new ArrayList<>();
        }
        // 查询权限
        List<Integer> permIds = new ArrayList<>();
        mapList.forEach(map -> {
            if (!permIds.contains(map.getPermId())) {
                permIds.add(map.getPermId());
            }
        });//已有就不添加，避免重复？那是否与distinct重复？确实重复，不过各自是在不同的层面进行的去重，一个在数据库查询时进行去重，一个在这个java构造结果时进行去重
        //关联表中只有id数据，所以在这里要再查出需要的url和name，具体要啥再说喽
        DemoPermExample example = new DemoPermExample();
        example.setDistinct(true);
        DemoPermExample.Criteria criteria = example.createCriteria();
        criteria.andDeletedEqualTo(false);
        criteria.andIdIn(permIds);
        if (annoStatus != null) {
            criteria.andAnonStatusEqualTo(annoStatus);
        }
        return permMapper.selectByExample(example);
    }

    @Override
    public List<DemoPerm> queryPermsByRoles(List<Integer> roles) {
        return queryPermsByRoles(roles, null);
    }//应对无匿名状态的形参时

    @Override
    public List<DemoPerm> queryAnonPerms() {
        DemoPermExample example = new DemoPermExample();
        example.setDistinct(true);
        DemoPermExample.Criteria criteria = example.createCriteria();
        criteria.andDeletedEqualTo(false);
        criteria.andAnonStatusEqualTo(AuthConstant.PERM_ANNO_STATUS_YES);//是匿名权限，这里只查匿名权限
        return permMapper.selectByExample(example);
    }
}
